#include "../../head/utils/BMachineControl.h"
#include <QProcess>

BMachineControl::BMachineControl(QObject *parent):QObject(parent){

}


QString BMachineControl::getHostMacAddress()
{

    QList<QNetworkInterface> nets = QNetworkInterface::allInterfaces();// 获取所有网络接口列表
    int nCnt = nets.count();
   // qDebug()<<nets;
    QString strMacAddr = "";
    for(int i = 0; i < nCnt; i ++)
    {
        // 如果此网络接口被激活并且正在运行并且不是回环地址，且该mac的ip地址不能是回环地址并且是ipv4地址，则就是我们需要找的Mac地址
        if(nets[i].flags().testFlag(QNetworkInterface::IsUp) &&
           nets[i].flags().testFlag(QNetworkInterface::IsRunning)
           && !nets[i].flags().testFlag(QNetworkInterface::IsLoopBack))
            {
            for (int j=0;j<nets[i].addressEntries().size() ;j++ ) {
            //该mac的ip地址不能为172.0.0.1，且需是ipv4地址
            if(nets[i].addressEntries().at(j).ip()!=QHostAddress::LocalHost
                    &&nets[i].addressEntries().at(j).ip().protocol()== QAbstractSocket::IPv4Protocol){
                    strMacAddr = nets[i].hardwareAddress();
                }
            }
        }
    }
   // qDebug()<<"strMacAddr"<<strMacAddr;
    return strMacAddr;
}


void encode(char str[],int n){
    char c;
    int i;
    for(i=0;i<strlen(str);++i){  //遍历字符串
        c=str[i];
        if(c>='a' && c<='z'){  //c是小写字母
            if(c+n%26<='z'){  //若加密后不超出小写字母范围
                str[i]=(char)(c+n%26);  //加密函数
            }else{  //加密后超出小写字母范围,从头开始循环小写字母
                str[i]=(char)(c+n%26-26);
            }
        }else if(c>='A' && c<='Z'){ //c为大写字母
            if(c + n%26 <= 'Z'){  //加密后不超出大写字母范围
                str[i]=(char)(c+n%26);
            }else{  //加密后超出大写字母范围,从头开始循环大写字母
                str[i]=(char)(c+n%26-26);
            }
        }else{  //不是字母，不加密
            str[i]=c;
        }
    }
  //  printf("\nAfter encode: \n");
 //   puts(str);  //输出加密后的字符串
}


QString BMachineControl::getCrypKey1(QString machineinfo){
    QCryptographicHash sha1(QCryptographicHash::Sha3_512);

    QByteArray datagram(machineinfo.toLatin1());

    for ( int i = 0; i != datagram.size(); ++i )
    {

        datagram[i] = datagram[i] ^ 'q' ^ 'y';
    }

    const char* tempConstChar = datagram.data();
    sha1.addData(tempConstChar);

    char strInfo[100] = {0};
    for(int i = 0 ; i< machineinfo.length() ; i++){
        strInfo[i] = machineinfo[i].toLatin1()+i+5;
    }
    encode(strInfo,3);

    QString activeCode = sha1.result().toHex().toUpper();
    for(int i = 0;i<strlen(strInfo);i++){
        activeCode = activeCode + strInfo[i];
    }



    return activeCode;
}

//生成密码散列的方法
QString BMachineControl::getCrypKey(QString machineinfo)
{
    QCryptographicHash sha1(QCryptographicHash::Sha3_512);

    QByteArray datagram(machineinfo.toLatin1());

    for ( int i = 0; i != datagram.size(); ++i )
    {

        datagram[i] = datagram[i] ^ 'q' ^ 'y';
    }

    const char* tempConstChar = datagram.data();
    sha1.addData(tempConstChar);

    QString activeCode = sha1.result().toHex().toUpper();

    return activeCode;
}

//实例 QSettings
//参数 1：注册表位置
//参数 2：操作 windows 注册表 QSettings::NativeFormat
//说明：QSettings::IniFormat 读写 ini 格式的配置文件，前面用过。
void BMachineControl::writeRegVal(QString key,QString value){
    QSettings *reg = new QSettings("HKEY_CURRENT_USER\\Software\\WinSys.com", QSettings::NativeFormat);

    //设定值有修改，没有创建。
    reg->setValue(key,value);
    //用完删除 QSettings
    delete reg;
}

QString BMachineControl::toUpperAndLower(QString src)
{
    for(int i = 0; i < src.count(); i++) {
        QChar curC = src.at(i);
        if(curC.isUpper()) {
            curC = curC.toLower();
        } else if(curC.isLower()){
            curC = curC.toUpper();
        }
        src[i] = curC;
    }
    return src;
}

QString BMachineControl::dateEnCryp(QString str){
    QByteArray text = str.toLocal8Bit();
    QByteArray by = text.toBase64();
    QString str1 = QString(by);

    return  toUpperAndLower(str1); // 大小写加密;
}

QString BMachineControl::dateDeCryp(QString str){
    QString str1 = toUpperAndLower(str); // 大小写解密
    QByteArray text = str1.toLocal8Bit();
    QByteArray by = text.fromBase64(text);

    return QString::fromLocal8Bit(by);
}

QString BMachineControl::writeTempRegVal(){
    QSettings *reg = new QSettings("HKEY_CURRENT_USER\\Software\\WinSys.com", QSettings::NativeFormat);

    QDateTime curDateTime = QDateTime::currentDateTime();
    QString test_first_time = dateEnCryp(curDateTime.toString("yyyy-MM-dd"));
    QString test_lastuse_time = dateEnCryp(curDateTime.toString("yyyy-MM-dd"));
    QString test_time_out = dateEnCryp(curDateTime.addDays(30).toString("yyyy-MM-dd"));

    reg->setValue("test_first_time",test_first_time);
    reg->setValue("test_lastuse_time",test_lastuse_time);
    reg->setValue("test_time_out",test_time_out);

    //删除 QSettings
    delete reg;
    return curDateTime.addDays(30).toString("yyyy-MM-dd");
}

void BMachineControl::getRegVal(){
    QSettings *reg = new QSettings("HKEY_CURRENT_USER\\Software\\WinSys.com", QSettings::NativeFormat);
    QString current_date = "2023-11-04";

    if(reg->value("encry").isNull() || reg->value("encry") != getCrypKey(getCpuId())){
        QDateTime curDateTime = QDateTime::currentDateTime();
        QString test_first_time = dateEnCryp(curDateTime.toString("yyyy-MM-dd"));
        QString test_lastuse_time = dateEnCryp(curDateTime.toString("yyyy-MM-dd"));
        QString test_time_out = dateEnCryp(curDateTime.addDays(30).toString("yyyy-MM-dd"));

        currentSettings.isReged = false;
        //判断 value 是否为空
        if(reg->value("test_first_time").isNull())
        {
            reg->setValue("test_first_time",test_first_time);
            currentSettings.test_first_time = dateDeCryp(test_first_time);
        }else{
            currentSettings.test_first_time = dateDeCryp(reg->value("test_first_time").toString());
        }

        reg->setValue("test_lastuse_time",test_first_time);
        currentSettings.test_lastuse_time = dateDeCryp(test_lastuse_time);





        if(reg->value("test_time_out").isNull())
        {
            reg->setValue("test_time_out",test_time_out);
            currentSettings.test_time_out = dateDeCryp(test_time_out);

        }else{
            currentSettings.test_time_out = dateDeCryp(reg->value("test_time_out").toString());
        }

    }else if(reg->value("encry") == getCrypKey(getCpuId())){
         currentSettings.isReged = true;
    }
    //删除 QSettings
    delete reg;
}



/*
功能: 获取CPU的ID
*/
QString BMachineControl::getCpuId()
{
    QString cmd="wmic cpu get processorid";
    QProcess p;
    p.start(cmd);
    p.waitForFinished();
    QString result = QString::fromLocal8Bit(p.readAllStandardOutput());
    QStringList list = cmd.split(" ");
    result = result.remove(list.last(), Qt::CaseInsensitive);
    result = result.replace("\r", "");
    result = result.replace("\n", "");
    result = result.simplified();
    return result;
}
